import java.util.ArrayDeque;
import java.util.Queue;

/**
 * Created whit IntelliJ IDEA.
 * Description：
 * User：ZHONGCHEN
 * Date:2022-02-12
 * Time:18:52
 */
/**1020. 飞地的数量
 * 给你一个大小为 m x n 的二进制矩阵 grid ，其中 0 表示一个海洋单元格、1 表示一个陆地单元格。
 * 一次 移动 是指从一个陆地单元格走到另一个相邻（上、下、左、右）的陆地单元格或跨过 grid 的边界。
 * 返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。
 *根据飞地的定义，如果从一个陆地单元格出发无法移动到网格边界，则这个陆地单元格是飞地。因此可以将所有陆地单元格分成两类：第一类陆地单元格和网格边界相连，这些陆地单元格不是飞地；第二类陆地单元格不和网格边界相连，这些陆地单元格是飞地。
 * 我们可以从网格边界上的每个陆地单元格开始深度优先搜索，遍历完边界之后，所有和网格边界相连的陆地单元格就都被访问过了。然后遍历整个网格，如果网格中的一个陆地单元格没有被访问过，则该陆地单元格不和网格的边界相连，是飞地。
 * 代码实现时，由于网格边界上的单元格一定不是飞地，因此遍历网格统计飞地的数量时只需要遍历不在网格边界上的单元格。
 */
class ints {
    Integer i;
    Integer j;

    public ints(Integer i, Integer j) {
        this.i = i;
        this.j = j;
    }
}

public class Test {
    //控制向上向下向左向右边
    public static int[][] num = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
    //标记图
    public static boolean[][] flag;
    static int m = 0;
    static int n = 0;

    public static int numEnclaves(int[][] grid) {
        //获取行
        m = grid.length;
        //获取列
        n = grid[0].length;
        //标记图,默认值是false
        flag = new boolean[m][n];
        //队列 存储的是四边为1的地方
        Queue<ints> queue = new ArrayDeque<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                //遍历矩阵四边
                if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
                    if (grid[i][j] == 1) {
                        ints s = new ints(i, j);
                        queue.add(s);
                    }
                }
            }
        }
        //按边框为1的地方进行遍历
        while (!queue.isEmpty()) {
            ints s = queue.poll();
            int i = s.i;
            int j = s.j;
            dfs(grid, i, j);
        }
        //最后遍历数组找飞地 当grid[i][j] == 1 且未被标识过的就是飞地
        int sum = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1 && flag[i][j] == false) {
                    sum++;
                }
            }
        }
        return sum;
    }

    public static void dfs(int[][] grid, int i, int j) {
        //合条件的直接return
        if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == 0 || flag[i][j] == true) {
            return;
        }
        flag[i][j] = true;
        for (int[] a : num) {
            //遍历该点的上下左右四个方向
            dfs(grid, i + a[0], j + a[1]);
        }
    }

    public static void main(String[] args) {
        //int[][] grid = {{0,0,0,0},{1,0,1,0},{0,1,1,0},{0,0,0,0}};
        int[][] grid = {{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}};
        System.out.println(numEnclaves(grid));
    }
}
